package org.lhl.readruler.connection

import lhl.kotlinextends.e
import org.lhl.readruler.bean.DataValue
import org.lhl.readruler.bean.DeviceStorage
import java.lang.Exception

/**
 * Author:  LuoHaoLun
 * Email :  506503279@qq.com
 * Date  :  2020/12/8
 */
const val HEAD_0A = 0
const val HEAD_0B = 1
const val TYPE = 2
const val SUB_TYPE = 3
const val DATA_LEN = 4
const val DATA = 5
const val END_E7 = 6
const val END_E8 = 7

class RulerParser : Parser {

    private var state = HEAD_0A
    private var type = 0
    private var subType = 0
    private var dataLength = 0
    private var data = mutableListOf<Int>()
    private var len = 2

    override fun parse(b: Int): AttEvent? {
        when (state) {
            HEAD_0A -> if (b == 0x0a) state = HEAD_0B

            HEAD_0B -> state = if (b == 0x0b) TYPE else HEAD_0A

            TYPE -> {
                type = b
                len = 2
                state = SUB_TYPE
                subType = 0
            }
            SUB_TYPE -> {
                len--
                if (len == 1) subType = b shl 8
                else subType += b
                if (len <= 0) {
                    len = 2
                    state = DATA_LEN
                    dataLength = 0
                }
            }
            DATA_LEN -> {
                len--
                if (len == 1) dataLength = b shl 8
                else dataLength += b
                if (len <= 0) {
                    state = DATA
                    len = dataLength
                    data.clear()
                }
            }
            DATA -> {
                len--
                data.add(b)
                if (len <= 0) {
                    state = END_E7
                }
            }
            END_E7 -> state = if (b == 0xe7) END_E8 else HEAD_0A
            END_E8 -> {
                state = HEAD_0A
                if (b != 0xe8) {
                    return null
                }

                if (type == 0x06) {// 设备序列号
                    return try {
                        val deviceNo = (data[4] shl 24) + (data[5] shl 16) + (data[6] shl 8) + data[7]
                        val id = deviceNo.toString().run {
                            var no = this
                            while (no.length < 10)
                                no = "0$no"
                            no
                        }
                        AttEvent(Event.DEVICE_ID, id)
                    } catch (e: Exception) {
                        null
                    }
                } else if (type == 0x02) {  //存储数据
                    return try {
                        val storage = DeviceStorage()
                        storage.stepIndex = subType
                        storage.allSteps = (data[0] shl 8) + data[1]
                        storage.totalAmount = (data[2] shl 8) + data[3]
                        storage.stepVolume = (data[4] shl 8) + data[5]
                        storage.startMileage = ((data[6] shl 24) + (data[7] shl 16) + (data[8] shl 8) + data[9]) / 1000.0
                        storage.interval = ((data[10] shl 8) + data[11]) / 1000.0 / 100.0
                        storage.batch = data[12]
                        val size = (data.size - 13) / 5
                        var mileage = storage.startMileage
                        var interval = 0.0
                        for (i in 0 until size) {
                            val value = DataValue()
                            value.type = data[13 + i * 5]
                            value.abTrack = if (value.type and 0x20 == 0) "左股" else "右股"
                            value.d1 = ((data[15 + i * 5] shl 8) + data[14 + i * 5]).toShort() / 100.0
                            value.d2 = ((data[17 + i * 5] shl 8) + data[16 + i * 5]).toShort() / 100.0
                            value.stepIndex = storage.stepIndex
                            value.pointIndex = i + 1
                            mileage += interval
                            value.mileage = mileage
                            storage.data.add(value)
                            interval = if (value.abTrack == "左股") storage.interval else (-1 * storage.interval)
                        }
                        "发送存储：$subType".e()
                        AttEvent(Event.DEVICE_STORAGE, storage)
                    } catch (e: Exception) {
                        e.printStackTrace()
                        null
                    }
                }
            }
            else -> {
                state = HEAD_0A
                return null
            }
        }
        return null
    }


    private fun parseData(data: IntArray): AttEvent? {
        return when (type) {
            // 设备序列号
            0x06 -> return try {
                val deviceNo = (data[4] shl 24) + (data[5] shl 16) + (data[6] shl 8) + data[7]
                val id = deviceNo.toString().run {
                    var no = this
                    while (no.length < 10) no = "0$no"
                    no
                }
                AttEvent(Event.DEVICE_ID, id)
            } catch (e: Exception) {
                null
            }

            else -> null
        }
    }

}